package targz

import (
	"archive/tar"
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// func: TarEncode(src, tarPath string) (err error)
// aim: tar.gz 打包

func TarEncode(src, tarPath string) (err error) {
	//创建tar 文件
	fw, err := os.Create(tarPath)
	if err != nil {
		return
	}
	defer fw.Close()

	//创建 gzip 流
	gw := gzip.NewWriter(fw)
	defer gw.Close()

	//创建 tar 流
	tw := tar.NewWriter(gw)
	defer tw.Close()

	err = filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			//如果是目录，不继续执行
			return err
		}

		fmt.Println(path)
		fr, err := os.Open(path)
		if err != nil {
			panic(err)
		}
		defer fr.Close()

		// 信息头
		h := new(tar.Header)
		h.Name = strings.ReplaceAll(path, `\`, `/`)  // 这里用path才能保存完成路径
		h.Size = info.Size()
		h.Mode = int64(info.Mode())
		h.ModTime = info.ModTime()

		// 写信息头
		err = tw.WriteHeader(h)
		if err != nil {
			panic(err)
		}

		// 写文件
		_, err = io.Copy(tw, fr)
		if err != nil {
			panic(err)
		}

		return nil
	})

	return nil
}

//tar.gz 解包
func TarDecode(tarfile, dir string) (err error) {
	if !(strings.HasSuffix(dir, "/") || strings.HasSuffix(dir, "\\")) {
		dir += "/"
	}
	//打开tar.gz 文件流
	fr, err := os.Open(tarfile)
	if err != nil {
		return
	}
	defer fr.Close()

	//打开gzip 流
	gr, err := gzip.NewReader(fr)
	if err != nil {
		return
	}
	defer gr.Close()

	tr := tar.NewReader(gr)
	for {
		hdr, err := tr.Next()
		if err != nil {
			if err == io.EOF {
				break
			} else {
				return err
			}
		}

		path := dir + hdr.Name
		fi := hdr.FileInfo()
		if fi.IsDir() {
			os.MkdirAll(path, fi.Mode())
		} else {
			dir := filepath.Dir(path)
			os.MkdirAll(dir, 0775)
			fw, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fi.Mode())
			if err != nil {
				log.Println(path, err)
				continue
			}
			_, err = io.Copy(fw, tr)
			if err != nil {
				log.Println(path, err)
				fw.Close()
				continue
			}
			fw.Close()
		}
	}
	return
}
